#include "stdafx.h"
#include "Regex.h"

Regex::Regex(const NWString& Expression)
{
	ExpressionGrammarTree.SetExpression(Expression);
	ExpressionGrammarTree.GetGrammerTree();
	//ExpressionGrammarTree.Print(ExpressionGrammarTree.Root);
	//wprintf(L"\n");
	ExpressionGrammarTree.GetCharClass(CharList);
	//CharList.Print();
	ExpressionNFA.BuildEpsilonNfa(ExpressionGrammarTree.Root,CharList);
	//ExpressionNFA.PrintNFA();
	ExpressionDFA.BuildDfa(ExpressionNFA.NFATable,CharList);
	//ExpressionDFA.PrintDFA();
	this->Expression = Expression;
}

Regex::MathResult Regex::Match(LPTSTR Expression)
{
	Regex::MathResult Result;
	int nLength = ExpressionDFA.Match(Expression);
	Result.Length = nLength;
	if(nLength > 0)
	{
		LPTSTR lpBuffer = new WCHAR[nLength + 1];
		wcsncpy(lpBuffer,Expression,nLength);
		lpBuffer[nLength] = 0;
		Result.Result = lpBuffer;
		delete[] lpBuffer;
	}
	Result.Matched = nLength > 0;
	/*LPTSTR lpBuffer = Expression,lpBuf = lpBuffer;
	int state = 0;
	List<int> L;
	L.Add(0);
	while(state != -1 && *lpBuffer)
	{
		state = ExpressionDFA.DFATable->Transit(state,*lpBuffer,CharList.CharList);
		L.Add(state);
		lpBuffer++;
	}
	int nLength = 0;
	for(int i=L.Size()-1;i>=0;i--)
		if(L[i] != -1 && ExpressionDFA.AcceptStatus[L[i]] == 1)
		{
			nLength = lpBuffer - lpBuf;
			break;
		}
		else lpBuffer--;
	if(nLength)
	{
		lpBuffer = new WCHAR[nLength + 1];
		wcsncpy(lpBuffer,Expression,nLength);
		lpBuffer[nLength] = 0;
		Result.Result = lpBuffer;
		delete[] lpBuffer;
	}
	Result.Matched = nLength > 0;*/
	return Result;
}

Regex::MathResult Regex::Match(NWString& Expression)
{
	Regex::MathResult Result;
	LPTSTR lpExpression = Expression.GetBuffer();
	int nLength = ExpressionDFA.Match(lpExpression);
	Result.Length = nLength;
	if(nLength > 0)
	{
		LPTSTR lpBuffer = new WCHAR[nLength + 1];
		wcsncpy(lpBuffer,lpExpression,nLength);
		lpBuffer[nLength] = 0;
		Result.Result = lpBuffer;
		delete[] lpBuffer;
	}
	Result.Matched = nLength > 0;
	return Result;
}